<?php
class MImage extends Model
{
    /**
    * @author MinhBL@ITLized.Com
    * @var mixed    Image data
    */
    var $image;
    
    /**
    * @author MinhBL@ITLized.Com
    * @var string   Path to folder that contain font files
    */
    var $font_dir;
    
    /**
    * @author MinhBL@ITLized.Com
    * @var array    List of font_code => font_filename
    */
    var $font_list = array();
    
    /**
    * Class contructor, set font_dir and build font_list
    * @author MinhBL@ITLized.Com
    */
    function MImage()
    {
        parent::Model();
        $this->font_dir = APPPATH . 'fonts/';
        $this->font_list();
    }
    
    /**
    * Generate preview images (300x75) for each font
    * @author MinhBL@ITLized.Com
    */
    function generate_font_sample()
    {
        $this->data["font_list"] = &$this->font_list;
        $this->data["font_sample"] = array();
        $preview_width = 300;
        $preview_height = 75;
        $preview_text = "ProKute";
        $preview_text_size = 24;
        if(!empty($this->font_list)) foreach($this->font_list as $font_code => $font_file)
        {
            $file_name = $font_code;
            $this->create_image($preview_width,$preview_height,array(0,0,0));
            $this->draw_text(floor($preview_height/3),floor($preview_height*2/3),$preview_text,$preview_text_size,$this->font_dir.$font_file);
            $this->output_image("fonts/".$file_name);
        }
    }
    
    /**
    * Generate a list of font and push it to $this->font_list
    * @author MinhBL@ITLized.Com
    */
    private function font_list()
    {
        $dh = @opendir($this->font_dir) or die(_("Can't read the font folder: ".$this->font_dir));
        $i = 0;
        while(FALSE !== ($file = readdir($dh)))
        {
            if((strpos($file,'.ttf')!==FALSE || strpos($file,'.otf')!==FALSE) && $file != 'texb.ttf')
            {
                $i++;
                $this->font_list["PKF".$i] = $file;
            }
        }
        $this->font_list;
    }
    
    /**
    * Draw text in bold
    * @author MinhBL@ITLized.Com
    * @param mixed $image       Image data
    * @param int $size          Size of text
    * @param int $angle         Angle of text
    * @param int $x_cord        The left position of the text
    * @param int $y_cord        The bottom base-line of the text
    * @param array $color       Color of the text in array(R,G,B);
    * @param string $fontfile   Path to font file 
    * @param string $text       Text to draw
    * @return mixed             Result of the draw action
    */
    function imagettftext_bold(&$image, $size, $angle, $x_cord, $y_cord, $color, $fontfile, $text)
    {
        $_x = array(1,1,0,0);
        $_y = array(1,0,1,0);
        for($n=0;$n<count($_x);$n++)
        {
            $text_to_image = @imagettftext(&$image, $size, $angle, $x_cord+$_x[$n], $y_cord+$_y[$n], $color, $fontfile, $text);
            if($text_to_image === FALSE) {
                imagestring(&$image,5,5,5,($n+1).": "._("Can't load font")." #".$font_code,$color);
                return FALSE;
            }
        }
        return $text_to_image;
    }
    
    /**
    * Initiate an image to start drawing
    * @author MinhBL@ITLized.Com
    * @param int $width                     Width of the image
    * @param int $height                    Height of the image
    * @param array $background_color        Background color of the image in array(R,G,B)
    * @param int $background_transparent    Transparent level (0..127)
    */
    function create_image($width, $height, $background_color=NULL, $background_transparent=FALSE) {
        $this->image = @imagecreate($width, $height) or die(_("Can't initiate image!"));
        $background_transparent = $background_transparent !== FALSE ? $background_transparent : 0;
        $background_color = empty($background_color) ? array(255,255,255) : $background_color;
        $background = imagecolorallocatealpha(&$this->image, $background_color[0], $background_color[1], $background_color[2], $background_transparent);
    }
    
    /**
    * Draw text into image
    * @author MinhBL@ITLized.Com
    * @param int $x_base            The left position of the text
    * @param int $y_base            The bottom base-line of the text
    * @param string $text           Text to draw
    * @param int $text_size         Size of text
    * @param string $font_code      Code of font used to draw
    * @param array $text_color      Color of the text in array(R,G,B);
    * @param bool $text_bold        Check if we draw bold text or normal text
    * @param int $angle             Angle of text 
    */
    function draw_text($x_base, $y_base, $text, $text_size, $font_code=FALSE, $text_color=NULL, $text_bold=FALSE, $transparent_level=FALSE, $angle=0) 
    {
        $text_color = empty($text_color) ? array(0,0,0) : $text_color;
        $transparent_level = $transparent_level !== FALSE ? $transparent_level : 0;
        $text_color = imagecolorallocatealpha(&$this->image, $text_color[0], $text_color[1], $text_color[2], $transparent_level);
        $text_font = !empty($font_code) ? 
                                            $this->font_dir.$this->font_list[$font_code] : 
                                            $this->font_dir . reset($this->font_list);
        if($text_bold) 
        {
            $text_to_image = @$this->imagettftext_bold(&$this->image, $text_size, $angle, $x_base, $y_base, $text_color, $text_font, $text);
        } 
        else 
        {
            $text_to_image = @imagettftext(&$this->image, $text_size, $angle, $x_base, $y_base, $text_color, $text_font, $text);
            if(!$text_to_image) 
            {
                imagestring($this->image,5,5,5,_("Can't load font #").$font_code,$text_color);
                return FALSE;
            }
        }
        return $text_to_image[2] - $text_to_image[0];
    }
    
    /**
    * Output image to client or to a file
    * @author MinhBL@ITLized.Com
    * @param string $file_name Name/Path of the image file to output data to. NULL to push to client!
    */
    function output_image($file_name = NULL)
    {
        if(empty($file_name))
        {
            header("Content-type: image/png");
            imagepng(&$this->image);
            imagedestroy(&$this->image);
        } else {
            imagepng(&$this->image,"../public_html/".$file_name.".png");
        }
    }    
}